/**
 * 用于消除异步fetch请求，实现同步代码；
 * 利用两次请求，第一次请求会抛出Promise对象，第二次请求会直接返回结果
 * @param func 需要执行的函数
 */
export function killFetchAsync(func: Function) {
  // 保存原来的fetch函数
  const oldFetch = window.fetch
  // 创建一个缓存对象，用于保存fetch请求的状态和结果
  const cache = {
    status: 'pending', // pending|fulfilled|rejected
    val: null
  }

  // 创建一个新的fetch函数
  function newFetch(params: any): Promise<Response> {
    // 如果fetch请求已经完成，则直接返回结果
    if (cache.status === 'fulfilled') {
      return cache.val as any
      // 如果fetch请求已经失败，则抛出错误
    } else if (cache.status === 'rejected') {
      throw cache.val
    }
    // 执行原来的fetch函数，并将结果保存到缓存中
    const p = oldFetch(params)
      .then((res) => res.json())
      .then((data) => {
        cache.status = 'fulfilled'
        cache.val = data
      })
      .catch((err) => {
        cache.status = 'rejected'
        cache.val = err
      })
    // 抛出Promise对象，以便在catch中捕获
    throw p
  }

  // 尝试执行传入的函数
  try {
    func()
    // 如果函数执行出错，则判断错误是否为Promise对象
  } catch (err) {
    if (err instanceof Promise) {
      // 如果是Promise对象，则在finally中恢复原来的fetch函数，并重新执行函数
      err.finally(() => {
        window.fetch = newFetch
        func()
        window.fetch = oldFetch
      })
    }
  }
  // 恢复原来的fetch函数
  window.fetch = oldFetch
}
